package Assignment_2_Classes;
//package Assignment_2_Classes;
import java.io.*;
import java.net.*;
import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.Scanner;
public class JennaKingsburyClientA2S15 {
  public static void main(String[] args) throws IOException
  {
    //Hard code servername
    FileOutputStream theFile = null;
    LinkedList<byte[]> fileBytes = new LinkedList();
    //This will print the time info
    String serverName = "pool.ntp.org";
    
    //Print IP address of NTP servers
    InetAddress address = InetAddress.getByName(serverName);
    System.out.println("NTP server name/IP address: " + address.getHostName() + "/" + address.getHostAddress());
    
    
    //Print IP address of NTP client
    InetAddress address2 = InetAddress.getByName("JennaKingsburyClientA2S15.java");
    System.out.println("NTP client name/IP address: " + address2.getLocalHost());
    
    
    //Send request
    DatagramSocket socket = new DatagramSocket();
    byte[] buf = new NTPMessage().toByteArray();
    DatagramPacket packet =
      new DatagramPacket(buf, buf.length, address, 123); 
    
    //Set the transmit timestamp just before sending the packet
    
    NTPMessage.encodeTimestamp(packet.getData(), 40,
                               (System.currentTimeMillis()/1000.0) + 2208988800.0);
    
    socket.send(packet);
    
    //Print port numbers that NTP server uses
    System.out.println("NTP server port number: " + packet.getPort());
    //Print port numbers that NTP client uses
    System.out.println("NTP client port number: " + socket.getLocalPort());
    //getLocalPort(): Returns the Internet Protocol (IP) port number of the interface on which the request was received
    System.out.println();  
    
    
    //Get response
    System.out.println("NTP request sent, waiting for response...\n");
    packet = new DatagramPacket(buf, buf.length);
    socket.receive(packet);
    
    
    //Immediately record the incoming timestamp
    double destinationTimestamp =
      (System.currentTimeMillis()/1000.0) + 2208988800.0;
    
    
    //Process response
    NTPMessage msg = new NTPMessage(packet.getData());
    
    //Corrected, according to RFC2030 errata
    
    double roundTripDelay = (destinationTimestamp-msg.originateTimestamp) -
      (msg.transmitTimestamp-msg.receiveTimestamp);
    
    double localClockOffset =
      ((msg.receiveTimestamp - msg.originateTimestamp) +
       (msg.transmitTimestamp - destinationTimestamp)) / 2;
    
    
    //Display response
    System.out.println("NTP server: " + serverName);
    System.out.println(msg.toString());
    
    System.out.println("T3 = " + NTPMessage.timestampToString(destinationTimestamp));
    System.out.println("T3 - T1 = " + NTPMessage.timeToDouble(destinationTimestamp, msg.originateTimestamp));
    
    socket.close();
    
    //Check first characters are c:\ and last is .mp3
    Scanner input = new Scanner(System.in);   
    Scanner inputFile = null;
    boolean fileFormat = true;
    boolean fileOpened = true;
    String filename;
    
    //Validate input
    do{
      System.out.print("Enter filename in the form c:\\path\\filename.mp3 : ");
      filename = input.nextLine();
      filename = filename.trim();
      if((!filename.startsWith("c:\\") && !filename.startsWith("C:\\")) || !filename.endsWith(".mp3")){
        fileFormat = false;
        System.err.println("File format invalid. Please re-enter file name.");
      }
      else{
        fileFormat = true;
        try{
          inputFile = new Scanner(new File(filename));
          fileOpened = true;
        }//End of try  
        catch(FileNotFoundException e){
          System.err.println("File not found. Please re-enter file name.");
          fileOpened = false;
        }
      }
    }while(!fileOpened || !fileFormat);
    
    //Send file to client
    DatagramSocket clientSocket=new DatagramSocket();
    
    InetAddress IPAddress=InetAddress.getByName("JennaKingsburyServerA2S15.java");
    
    byte[] sendData=new byte[1024];
    byte[] receiveData=new byte[1024];
    String sentence = filename;
    sendData=sentence.getBytes();
    DatagramPacket sendPacket=
      new DatagramPacket(sendData, sendData.length,IPAddress, 33312);
    clientSocket.send(sendPacket);
    
    DatagramPacket receivePacket=
      new DatagramPacket(receiveData, receiveData.length);
    clientSocket.receive(receivePacket);
    
    
    //Immediately record the incoming timestamp
    destinationTimestamp =
      (System.currentTimeMillis()/1000.0) + 2208988800.0;
    
    String modifiedSentence=new String(receivePacket.getData());
    System.out.println("File recieved from server: " + modifiedSentence.trim());
    System.out.println("It was recieved at time: " + NTPMessage.timestampToString(destinationTimestamp));
    
    
    //fileSize records the file size of the packet to be sent
    //It is used to exit loop which is run to copy the file down
    int fileSizeInBytes = Integer.parseInt(modifiedSentence.trim());
    //Used to exit loop once all the data is recieved
    int bytesReceived = 0;
    int messageSize = 1024;
    boolean go = false;
    String fileLocation="";
    System.out.println("The File Size in Bytes is: " + fileSizeInBytes);
    
    while(bytesReceived <fileSizeInBytes){
      receiveData = new byte[1024];
      //this if-else statement decides the size of the incoming []byte array
      if(bytesReceived +receiveData.length < fileSizeInBytes){
        messageSize = receiveData.length;
      }
      else
        messageSize = fileSizeInBytes - bytesReceived;
      
      receivePacket = new DatagramPacket(receiveData, messageSize);
      clientSocket.receive(receivePacket);
      
      receiveData = receivePacket.getData();
      bytesReceived = bytesReceived + messageSize;
      fileBytes.add(receiveData);
    }  
    System.out.println("File transfer finished.");
    
    destinationTimestamp =
      (System.currentTimeMillis()/1000.0) + 2208988800.0;
    System.out.println("Time Finished: " + NTPMessage.timestampToString(destinationTimestamp));
    while(!go) {
      System.out.print("Enter file destination in the form c:\\path\\filename.mp3 : ");
      
      fileLocation = input.nextLine();
      fileLocation = fileLocation.trim();
      
      if(!fileLocation.startsWith("c:\\") && !fileLocation.startsWith("C:\\")) {
        go = false;
      } 
      else if(!fileLocation.endsWith(".mp3")) {
        go = false;
      }
      else
        go = true;
    }//end while
    
    System.out.println(fileLocation);
    
    File newFile = new File(fileLocation);
    newFile.createNewFile();
    theFile = new FileOutputStream(newFile);
    
    while(!fileBytes.isEmpty()){
     theFile.write(fileBytes.removeFirst());
     }//End of while
    
    theFile.close();
    clientSocket.close(); 
  }//End of main
}
